package com.gxd.redis.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * @Author:gxd
 * @Description:
 * @Date: 15:06 2018/1/5
 * @Modified By:
 */
@ConditionalOnProperty("redis.cache.enabled")
@ConfigurationProperties(prefix = "redis.cache")
@Component("gxdRedisProperties")
public class RedisProperties {
    private static final Logger logger = LoggerFactory.getLogger(RedisProperties.class);

    private String nodes;

    private int maxRedirects;

    private int expireTime;

    /**
     * Redis统一key前缀
     */
    private String bizKey;

    /**
     * 连接池中的最大空闲连接
     */
    private int maxIdle;

    /**
     * 连接池中的最小空闲连接
     */
    private int minIdle;

    /**
     * 连接超时时间（毫秒）
     */
    private int timeout;

    /**
     * 在borrow一个jedis实例时，是否提前进行alidate操作；如果为true，则得到的jedis实例均是可用的；
     */
    private boolean testOnBorrow;

    /**
     * 在return给pool时，是否提前进行validate操作；
     */
    private boolean testOnReturn;

    /**
     * 表示当borrow一个jedis实例时，最大的等待时间，如果超过等待时间，则直接抛出JedisConnectionException；
     */
    private int maxWaitMillis;

    /**
     * 出现异常最大重试次数
     */
    private int maxAttempts;

    /**
     * 返回值的超时时间
     */
    private int soTimeout;

    private int connectionTimeout;

    private int maxTotal;

    /**
     * 控制一个pool可分配多少个jedis实例，通过pool.getResource()来获取；如果赋值为-1，
     * 则表示不限制；如果pool已经分配了maxActive个jedis实例，
     * 则此时pool的状态就成exhausted了，在JedisPoolConfig
     */
    private int maxActive;

    /**
     * 单实例redis配置
     */
    private String host;
    private int port;
    private String password;

    private int database;


    /**
     * 每隔60秒定期检查空闲连接
     */
    private int timeBetweenEvictionRunsMillis = 60000;

    /**
     * 连接在池中保持空闲而不被空闲连接回收器线程回收的最小时间值,单位毫秒
     */
    private int  minEvictableIdleTimeMillis = 120000;

    /**
     * 空闲连接扫描时，每次最多扫描的连接数,一般设置为-1，全部扫描
     */
    private int numTestsPerEvictionRun=-1;

    public int getNumTestsPerEvictionRun() {
        return numTestsPerEvictionRun;
    }

    public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
        this.numTestsPerEvictionRun = numTestsPerEvictionRun;
    }


    public int getMaxTotal() {
        return maxTotal;
    }

    public int getTimeBetweenEvictionRunsMillis() {
        return timeBetweenEvictionRunsMillis;
    }

    public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) {
        this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
    }

    public int getMinEvictableIdleTimeMillis() {
        return minEvictableIdleTimeMillis;
    }

    public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {
        this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
    }

    public void setMaxTotal(int maxTotal) {
        this.maxTotal = maxTotal;
    }

    public boolean getTestOnReturn() {
        return testOnReturn;
    }

    public void setTestOnReturn(boolean testOnReturn) {
        this.testOnReturn = testOnReturn;
    }

    public int getSoTimeout() {
        return soTimeout;
    }

    public void setSoTimeout(int soTimeout) {
        this.soTimeout = soTimeout;
    }

    public int getMaxAttempts() {
        return maxAttempts;
    }

    public void setMaxAttempts(int maxAttempts) {
        this.maxAttempts = maxAttempts;
    }

    public String getNodes() {
        return nodes;
    }

    public void setNodes(String nodes) {
        this.nodes = nodes;
    }

    public int getMaxRedirects() {
        return maxRedirects;
    }

    public void setMaxRedirects(int maxRedirects) {
        this.maxRedirects = maxRedirects;
    }

    public int getMaxIdle() {
        return maxIdle;
    }

    public void setMaxIdle(int maxIdle) {
        this.maxIdle = maxIdle;
    }

    public int getMinIdle() {
        return minIdle;
    }

    public void setMinIdle(int minIdle) {
        this.minIdle = minIdle;
    }

    public int getTimeout() {
        return timeout;
    }

    public int getConnectionTimeout() {
        return connectionTimeout;
    }

    public void setConnectionTimeout(int connectionTimeout) {
        this.connectionTimeout = connectionTimeout;
    }

    public int getMaxActive() {
        return maxActive;
    }

    public void setMaxActive(int maxActive) {
        this.maxActive = maxActive;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    public boolean getTestOnBorrow() {
        return testOnBorrow;
    }

    public void setTestOnBorrow(boolean testOnBorrow) {
        this.testOnBorrow = testOnBorrow;
    }

    public int getMaxWaitMillis() {
        return maxWaitMillis;
    }

    public void setMaxWaitMillis(int maxWaitMillis) {
        this.maxWaitMillis = maxWaitMillis;
    }

    public int getExpireTime() {
        return expireTime;
    }

    public void setExpireTime(int expireTime) {
        this.expireTime = expireTime;
    }

    public String getBizKey() {
        return bizKey;
    }

    public void setBizKey(String bizKey) {
        this.bizKey = bizKey;
    }

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getDatabase() {
        return database;
    }

    public void setDatabase(int database) {
        this.database = database;
    }

    @PostConstruct
    private void initialize() {
        if(nodes != null && nodes.contains(",")) {
            logger.debug(
                    "RedisClusterProperties initialized - expireTime: {}, nodes: {}, maxRedirects: {},bizKey: {},maxAttempts: {},timeout: {},maxIdle: {},minIdle: {},maxWaitMillis: {}",
                    expireTime, nodes, maxRedirects, bizKey, maxAttempts, timeout, maxIdle, minIdle, maxWaitMillis);
        }else{
            logger.debug(
                    "RedisSingleProperties initialized - expireTime: {}, host: {},port: {}, password: {},bizKey: {},timeout: {},maxIdle: {},minIdle: {},maxWaitMillis: {} ,database: {}",
                    expireTime, host, port, password, bizKey, timeout, maxIdle, minIdle, maxWaitMillis,database);

        }
    }

    @Override
    public String toString() {
        if (nodes != null && nodes.contains(",")) {
            return String.format(
                    "[RedisClusterProperties] expireTime: %d, nodes: %s, maxRedirects: %d, bizKey: %s, maxAttempts: %d, timeout: %d, maxIdle: %d, minIdle: %d, maxWaitMillis: %d",
                    expireTime, nodes, maxRedirects, bizKey, maxAttempts, timeout, maxIdle, minIdle, maxWaitMillis);
        } else {
            return String.format(
                    "[RedisSingleProperties] expireTime: %d, host: %s, port: %d, password: %s, bizKey: %s, maxAttempts: %d, timeout: %d, maxIdle: %d, minIdle: %d, maxWaitMillis: %d",
                    expireTime, host, port, password, bizKey, maxAttempts, timeout, maxIdle, minIdle, maxWaitMillis);

        }
    }
}